/*
 * pci.h
 *
 *  Created on: 2021年3月19日
 *      Author: root
 */

#ifndef INCLUDE_HARDWARECOMMUNICATION_PCI_H_
#define INCLUDE_HARDWARECOMMUNICATION_PCI_H_

#include <hardwarecommunication/port.h>
#include <hardwarecommunication/interrupts.h>
#include <common/types.h>
#include <drivers/driver.h>
#include <memorymanagement.h>


namespace myos{
namespace hardwarecommunication{

	//枚举类型
	enum BaseAddressRegisterType{
		MemoryMapping=0 ,  //内存映射
		InputOutput=1
	};

	class BaseAddressRegister{
		public:
		bool prefetchable;
		myos::common::uint8_t* address;
		myos::common::uint32_t size;
		BaseAddressRegisterType type;
	};


	class PeripheralComponentInterconnectDeviceDescriptor{
	public:
		myos::common::uint32_t portBase;
		myos::common::uint32_t interrupt;

		myos::common::uint16_t bus;
		myos::common::uint16_t device;
		myos::common::uint16_t function;

		myos::common::uint16_t vendor_id;
		myos::common::uint16_t device_id;

		myos::common::uint8_t  class_id;
		myos::common::uint8_t subclass_id;
		myos::common::uint16_t interface_id;

		common::uint16_t revision;

		PeripheralComponentInterconnectDeviceDescriptor();
		~PeripheralComponentInterconnectDeviceDescriptor();
	};

	//PIC
	class PeripheralComponentInterconnectController{
		Port32Bit dataPort;
		Port32Bit commandPort;

	public:
		PeripheralComponentInterconnectController();
		~PeripheralComponentInterconnectController();

		common::uint32_t Read(common::uint16_t bus,common::uint16_t device,common::int16_t function,common::int32_t registeroffset);
		void Write(common::uint16_t bus,common::uint16_t device,common::uint16_t function,common::uint32_t registeroffset,common::uint32_t value);
		bool DeviceHasFunctions(common::uint16_t bus,common::uint16_t device);


		void SelectDrivers(myos::drivers::DriverManager*  driverManager,myos::hardwarecommunication::InterruptManager* interrupt);
		drivers::Driver* GetDriver(PeripheralComponentInterconnectDeviceDescriptor dev,myos::hardwarecommunication::InterruptManager* interrupt);
		PeripheralComponentInterconnectDeviceDescriptor GetDeviceDescriptor(common::uint16_t bus,common::uint16_t device,common::uint16_t function);
		BaseAddressRegister GetBaseAddressRegister(common::uint16_t bus,common::uint16_t device,common::uint16_t function,common::uint16_t bar);
		};
	}
}





#endif /* INCLUDE_HARDWARECOMMUNICATION_PCI_H_ */
